Zhangzhe's Blog

The projection of my life.

0%

A Survey of Large Language Models

URL

TL;DR

  • 一篇关于大模型的综述,截止到 2023 年 9 月 ,对现有的大模型做了较为详细的梳理。

Survey

1. Introduction

  • LLM (large language model)PLM (pretrain language model) 主要有三个区别:
    1. LLM 表现出一些令人惊讶的涌现能力,这些能力可能在以前较小的 PLM 中没有观察到。
    2. LLM 将彻底改变人类开发和使用人工智能算法的方式,与小型 PLM 不同,访问 LLM 的主要方法是通过提示接口(例如 GPT-4 API)。
    3. LLM 的发展不再明确区分研究和工程。训练 LLM 需要在大规模数据处理和分布式并行训练方面具有丰富的实践经验。
  • 本文主要从四个方面介绍 LLM 的进展:
    1. 预训练:如何训练出一个有能力的 LLM
    2. 适配微调:如何从有效性和安全性两个角度有效地微调预训练的 LLM
    3. 使用:如何利用 LLM 解决各种下游任务
    4. 能力评估:如何评估 LLM 的能力和现有的经验性发现

2. Overview

2.1 大语言模型的涌现能力

LLM 的涌现能力(Emergent Abilities)被正式定义为:在小型模型中不存在但在大型模型中产生的能力,这里介绍三种典型涌现能力:

1. In-context learning(上下文学习)

  • ICL 能力是由 GPT-3 正式引入的:假设已经为语言模型提供了一个自然语言指令和/或几个任务演示,它可以通过完成输入文本的单词序列的方式来为测试实例生成预期的输出,而无需额外的训练或梯度更新。

2. Instruction following(指令遵循)

  • 通过使用自然语言描述的混合多任务数据集进行微调(称为指令微调),LLM 在未见过的以指令形式描述的任务上表现出色。

3. Step-by-step reasoning:(逐步推理)

  • 通过使用思维链(Chain-of-Thought, CoT)提示策略,LLM 可以通过利用包含中间推理步骤的提示机制来解决这类任务,从而得出最终答案。
    LLM_survey_1.png

2.2 大语言模型的关键技术

LLM 的关键技术主要分为以下五个方面:

1. Scaling(扩展)

  • Transformer 语言模型存在明显的扩展效应,更大的模型/更大的数据规模/更多的训练计算通常会导致模型能力的提升。

2. Training(训练)

  • 分布式训练算法是学习 LLM 网络参数所必需的,其中通常联合使用各种并行策略。
  • 为了支持分布式训练,已经发布了一些优化框架来促进并行算法的实现和部署,例如 DeepSpeedMegatron-LM
  • 此外,优化技巧对于训练稳定性和模型性能也很重要,例如预训练以克服训练损失激增和混合精度训练等。

3. Ability eliciting(能力引导)

  • 在大规模语料库上预训练之后,LLM 具备了作为通用任务求解器的潜在能力。
  • 然而,当 LLM 执行一些特定任务时,这些能力可能不会显式地展示出来。
  • 作为技术手段,设计合适的任务指令或具体的 ICL 策略可以激发这些能力。

4. Alignment tuning(对齐微调)

  • InstructGPT 设计了一种有效的微调方法,使 LLM 能够按照期望的指令进行操作,其中利用了 基于人类反馈的强化学习技术(RLHF),采用精心设计的标注策略,它将人类反馈纳入训练循环中。

5. Tools manipulation(操作工具)

  • 利用外部工具可以进一步扩展 LLM 的能力。例如,LLM 可以利用计算器进行准确计算,利用搜索引擎检索未知信息,这种机制可以广泛扩展 LLM 的能力范围。

2.3 GPT 系列模型的演进

LLM_survey_2.png

1. GPT-1: 2018 年

  • 2018 年,OpenAI 发布了 GPT-1,代表生成式预训练(Generative Pre-Training)。
  • GPT-1 是基于生成型的、仅含有解码器Transformer 架构开发的,并采用了无监督预训练和有监督微调的混合方法。
  • GPT-1GPT 系列模型建立了核心架构,并确立了对自然语言文本进行建模的基本原则,即预测下一个单词

2. GPT-2: 2019 年

  • 将参数规模增加到了 15 亿,并使用大规模的网页数据集 WebText 进行训练。
  • 它旨在通过无监督语言建模来执行任务,而无需使用标记数据进行显式微调
  • 尽管 GPT-2 旨在成为一个无监督的多任务学习器,但与监督微调的 SOTA 方法相比,其整体性能仍然较差。

3. GPT-3: 2020 年

  • 参数规模增加到了 175 亿,引入了 ICL 的概念,它是以小样本或零样本的方式使用 LLMICL 可以指导 LLM 理解以自然语言文本的形式给出的任务。
  • GPT-3 不仅在各种 NLP 任务中表现出色,而且在一些需要推理或领域适配能力的特殊设计的任务中也表现出色。
  • GPT-3 可以被视 为从 PLMLLM 进化过程中的一个重要里程碑。它通过实证证明,将神经网络扩展到大的规模可以大幅增加模型的能力。
  • OpenAI 为了提高 GPT-3 的性能,使用了两种策略:
    1. 使用代码数据进行训练
      • 原始的 GPT-3 模型(在纯文本上进行预训练)的一个主要限制在于缺乏复杂任务的推理能力,例如完成代码和解决数学问题。
      • OpenAI2021.07 推出了 Codex,这是一个在大量 GitHub 代码上微调的 GPT 模型,Codex 可以解决非常困难的编程问题,并且在数学问题上有显著的性能提升。
      • 实际上,GPT-3.5 模型是在基于代码的 GPT 模型(code-davinci-002)的基础上开发的。
    2. 与人类对齐
      • InstructGPT2022.01 提出,以改进 GPT-3 模型与人类对齐能力,正式建立了一个三阶段的基于人类反馈的强化学习(RLHF)算法。
      • 除了提高指令遵循能力之外,RLHF 算法对于缓解有害或有毒内容的生成问题十分有效,这对于 LLM 在实践中的安全部署至关重要。
      • OpenAI 在对齐研究中的方法,总结了三个有前途的方向:
        1. 使用人类反馈训练 AI 系统
        2. 协助人类评估
        3. 做对齐研究

4. ChatGPT: 2022 年

  • 它是以类似 InstructGPT 的方式进行训练的(在原始文章中称为“InstructGPT 的姊妹模型”),但专门针对对话能力进行了优化。
  • ChatGPT 训练数据是通过将人类生成的对话(扮演用户和 AI 两个角色)与 InstructGPT 数据集结合起来以对话形式生成。
  • ChatGPT 在与人类的交流中表现出卓越的能力:
    1. 拥有丰富的知识库
    2. 擅长解决数学问题
    3. 准确追踪多轮对话中的上下文
    4. 与人类的价值观保持一致以确保被安全使用
  • ChatGPT 支持了插件机制,进一步通过已有工具或应用扩展了 ChatGPT 的功能。

5. GPT-4: 2023 年

  • 将文本输入扩展到多模态信号,性能有大幅提升。
  • GPT-4 对于具有恶意或挑衅的提问的响应更加安全,并采用了多种干预策略来减轻语言模型的可能问题,如幻觉、隐私和过度依赖。

3. 大语言模型公开可用资源

3.1 公开可用的模型检查点或 API

LLM_survey_3.png
LLM_survey_4.png
LLM_survey_5.png

3.2 常用预训练语料库

常用的用于预训练的语料库有:

1. Books

  1. BookCorpus 是之前小规模模型(如 GPTGPT-2)中常用的预训练数据集,包含超过 11,000 本电子书,涵盖广泛的主题和类型(如小说和传记)。
  2. Gutenberg 是更大的数据语料库,包含超过 70,000 本文学作品,包括小说、散文、诗歌、戏剧、历史、科学、哲学和其他公共领域的作品。
  3. GPT-3 中使用到的 Books1Books2 是比 Gutenberg 大的多的语料库,但并未开源。

2. CommonCrawl

  1. CommonCrawl 是最大的开源网络爬虫数据库之一,能力达到了百万亿字节级别,已经被广泛运用于训练 LLM
  2. 由于网络数据中存在大量的噪音和低质量信息,因此使用前需要进行数据预处理。目前有四个较为常用的基于 CommonCrawl 的过滤数据集:
    1. C4
    2. CC-Stories
    3. CC-News
    4. RealNews
  1. Reddit 是一个社交媒体平台,用户可以在上 面提交链接和帖子,其他人可以通过“赞同”或“反对”投票。高赞的帖子通常被认为对多数用户是有帮助的,可以用来创建高质量的数据集。
  2. WebText 就是一个著名的基于 Reddit 的 语料库,它由 Reddit 上高赞的链接组成,但尚未公开
  3. 作为替代,有一个易于获取的开源替代品叫做 OpenWebText
  4. 另一个从 Reddit 中提取的语料库是 PushShift.io.

4. Wikipedia

  1. Wikipedia 是一个在线百科全书,包含大量高质量的文章,涵盖各种主题。其中大部分文章都采用解释性写作风格(并支持引用),覆盖了多种不同语言和广泛的知识领域。

5. Code

  1. 为了收集代码数据,现有工作主要是从互联网上爬取有开源许可证的代码。代码数据有两个主要来源:
    1. 包括开源许可证的公共代码库(例如 GitHub
    2. 与代码相关的问答平台(例如 StackOverflow
  2. Google 公开发布了 BigQuery 数据集,其中包括各种编程语言的大量开源许可证代码片段, 是一个典型的代码数据集。

6. Other

  1. The Pile 是一个大规模、多样化、开源的文本数据集,有超过 800GB 数据,内容包括书籍、网站、代码、科学论文和社交媒体平台等。它由 22 个多样化的高质量子集构成。
  2. ROOTS 由各种较小的数据集(完全为 1.61 TB 的文本)组成,涵盖了 59 种不同的语言(包含自然语言和传统语言)。

7. 一些经典模型使用的预训练语料库

  1. GPT-3(175B) 是在混合数据集(共 3000 亿 token)上进行训练的,包括:
    1. CommonCrawl
    2. WebText2
    3. Books1
    4. Books2
    5. Wikipedia
  2. PaLM(540B) 使用了共包含 7800 亿 token 的数据集,包括:
    1. 社交媒体对话
    2. 过滤后的网页
    3. 书籍
    4. Github
    5. 多语言维基百科
    6. 新闻
  3. LLaMA 使用了更多的数据预训练,其中 LLaMA(6B)LLaMA(13B) 的训练数据大小为 1.0 万亿 token,而 LLaMA(32B)LLaMA(65B) 使用了 1.4 万亿 token,包括:
    1. CommonCrawl
    2. C4
    3. Github
    4. Wikipedia
    5. 书籍
    6. ArXiv
    7. StackExchange

3.3 常用 Fine-tuning 语料库

1. instrction tuning (指令微调) 常用数据集

instrction tuning (指令微调) 过程可将预训练好的多任务模型在 Zero-shot 任务上表现更好。

  1. NLP task dataset
    1. P3 (Public Pool of Prompts)
      1. 一个涵盖各种自然语言处理任务的 Prompted 英文数据集集合,Prompt 是输入模板和目标模板的组合。
      2. 模板是将数据示例映射到自然语言输入和目标序列的函数。例如,在自然语言推理(NLI)数据集的情况下,数据示例将包括 Premise(前提)、Hypothesis(假设)和 Label(标签) 字段。
      3. 输入模板可以定义为:“如果 {Premise} 为真,则 {Hypothesis} 也为真吗?”,而目标模板可以定义为:选择的选项为 Choices[label]。这里的 Choices 是特定于 Prompt 的元数据,包含对应于标签为包含(0)、中性(1)或矛盾(2)的选项 yesmaybeno
    2. FLAN 使用的 instrction tunning 数据集
      1. FLAN 实际上是 google 的 《Finetuned Language Models Are Zero-Shot Learners》提出的模型,该模型用了大量的自然语言理解(NLU)和自然语言生成(NLG)任务数据集做指令微调。
        LLM_survey_6.png
      2. 指令微调后的模型在 Zero-shot 任务上表现更好。
  2. Daily chat dataset
    1. ShareGPT:由用户资源上传的和 ChatGPTGPT4 的对话,总量大约 90,000 组对话。
    2. OpenAssistant:多语言的人类和 AI 助手的对话,包含 35 种语言,66,497 组对话和 461,292 个人类标注。
    3. Dolly:由 Databricks 公司制作的 15,000 条英文人类对话,包含 7 大子类:
      1. 头脑风暴
      2. 内容生成
      3. 信息提取
      4. 摘要
      5. 分类
      6. 开卷考试的质量保证 (closed-book quality assurance)
      7. 闭卷考试的质量保证 (open-book quality assurance)
  3. 合成数据
    1. Self-Instruct-52K:一个由 Self-Instruct 框架生成的指令遵循数据集,共 82,000 个实例包含约 52,000 条指令。
    2. Alpaca:一个用于训练和评估指令遵循型语言模型的集合,它包含了 52,000 条独特的指令和相应的输出,这些数据是基于 OpenAItext-davinci-003 模型自动生成的。
    3. Baize:是一个开源的多轮对话数据集,它通过让 ChatGPT 自我对话生成,旨在为训练和评估对话模型提供高质量的语料资源。对话全部为英文,共包含 111.5K 个实例。

2. Alignment(对齐) 常用数据集

Alignment(对齐)过程的目的是让 LLM 对齐人类的价值观和偏好。Alignment 数据集需要是高质量的、有帮助的、诚实的、无害的。

  1. HH-RLHF :是由 Anthropic 公司收集的,用于训练和评估强化学习中的偏好(或奖励)模型的数据集,包含约 169K 实例。这个数据集包含两部分:
    1. 有益和无害性的人类偏好数据
    2. 红队对抗数据
  2. SHP:包含 385,000 条人类偏好的数据集,这些偏好是对 18 个不同主题领域中问题/指令的回答进行的。
  3. PKU-SafeRLHF:由北京大学团队开发的,用于支持和推动安全强化学习(RLHF)技术的研究和发展的数据集。这个数据集是目前为止最大的多轮 RLHF 数据集之一,规模达到 100 万条,包含了一系列安全偏好的标注,这些标注覆盖了侮辱、歧视、犯罪、心理伤害、悲观情绪、色情、隐私等多种维度,用于对 RLHF 技术进行细粒度的约束价值对齐。
  4. Stack Exchange Preferences:是一个从 Stack Overflow 数据转储中提取的问答对数据集,它被设计用于偏好学习(preference learning)。这个数据集包含了大量的问题和答案,其中答案基于得票数进行了评分。数据集的大小超过了 20GB,并且包含了数百万条问题和答案对。
  5. Sandbox Alignment Data 是一个由大型语言模型(LLM)生成的对齐数据集,包含约 169K 个实例,它包含了来自模拟社交互动环境 SANDBOX 的反馈。在 SANDBOX 中,模型模拟了人类社会中的交互,通过这种方式生成的对话数据被用来训练和评估语言模型,使其更好地符合人类的价值观和社交规范。

3.4 常用代码库资源

1. Transformers

  • 一个使用 Transformer 架构构建模型的开源 Python 库,由 Hugging Face 开发和维护。它具有简单和用户友好的 API,方便使用和定制各种预训练模型。

2. DeepSpeed

  • Microsoft 开发的深度学习优化库(与 PyTorch 兼容),已用于训练多个 LLM,例如 MTNLGBLOOM。它提供了各种分布式训练优化技术的支持,例如内存优化(ZeRO 技术、梯度检查点)和管道并行。

3. Megatron-LM

  • NVIDIA 开发的深度学习库,用于训练 LLM。它提供了丰富的分布式训练优化技术,包括模型和数据并行、混合精度训练和 FlashAttention。这些优化技术可以大大提高训练效率和速度,并实现 GPU 间的高效分布式训练。

4. JAX

  • Google 开发的用于高性能机器学习算法的 Python 库,允许用户在带有硬件加速(例如 GPUTPU)的情况下进行数组的高效运算。它可以在各种设备上进行高效计算,还支持自动微分和即时编译等特色功能。

5. Colossal-AI

  • HPC-AI Tech 开发的用于训练大规模人工智能模型的深度学习库。它基于 PyTorch 实现,并支持丰富的并行训练策略。

6. BMTrain

  • OpenBMB 开发的用于以分布式方式训练大规模参数模型的高效库,强调代码简洁、低资源占用和高可用性。

7. FastMoE

  • 一种专门用于 MoE(即混合专家)模型的训练库。

8. vLLM

  • 一个快速、内存高效、易用的 LLM 代码库,用于 LLM 的推理和服务。

9. DeepSpeed-MII

  • DeepSpeed Model Implementations for Inference,一个比 vLLM 更快的模型推理服务框架。

10. DeepSpeed-Chat

  • 基于 DeepSpeed 的一键式训练 RLHF,提速 15 倍。

4. 预训练

预训练为 LLM 的语言理解和生成能力奠定了基础。

4.1 数据收集和处理

1. 数据来源

  1. 通用文本数据
    1. Webpages
    2. Conversation text
    3. Books
  2. 专用文本数据
    1. 多语音文本
    2. 科学文本
    3. 代码

2. 数据处理

一个好用的数据处理代码库是 Data-Juicer

  1. 质量过滤
    为删除语料库中的低质量数据,通过有两种方式:基于分类器的方法基于启发式的方法
    1. 基于分类器的方法
      1. 通常采用高质量文本(例如 wikipedia)作为正样本,候选文本作为负样本,训练二分类器,用于给出一个文本的质量分数。
      2. 预计分类器的质量过滤方法可能会 无意识的删除口语化、方言、社会语音的文本
    2. 基于启发式的方法
      启发式方法通常采用一系列预设的规则来过滤低质量文本,具体的方法有:
      1. 基于语言的过滤:例如删除小语种文本等。
      2. 基于度量的过滤:例如基于困惑度(perplexity)来检测和删除不自然的文本。
      3. 基于统计的过滤:例如根据标点符号的分布、符合和单词的比例等删除。
      4. 基于关键词的过滤:例如删除 HTML 标签、超链接、模板等。
  2. 数据去重
    1. 现有研究表明,重复数据会降低语料库的多样性,可能导致训练过程不稳定,从而影响模型性能。
    2. 三种粒度的数据去重:
      1. 句子级
      2. 文档级
      3. 数据集级
  3. 隐私去除
    1. 预训练数据大多来自网络,可能包含敏感隐私信息,存在隐私泄露风险。因此需要从数据集中删除 personally identifiable information(可识别个人信息,PII)。
    2. 一种有效的删除方法是通过规则(例如:关键字识别)来检测和删除可识别各人信息(例如:姓名、电话、地址等)。
    3. 现有研究表明,LLM 在隐私攻击下的脆弱性可能归因于预训练数据中存在重复的可识别个人信息。
  4. 分词(Tokenization
    分词也是数据预处理的关键步骤,它的目的是将原始文本分割成词序列,随后用作 LLM 的输入。常用的分词方式有以下三种:
    1. BPE (Byte-Pair Encoding tokenization) 字节对编码,计算过程如下:
      1. 首先将文本拆分成字母和分隔符,并统计每个字母或分隔符出现的频率。
      2. 计算任意两个字母/分隔符合并后出现的频率,找到最高频的字母/分隔符对合并,重新统计词频并更新词表。
      3. 重复第二步,直到词表大小满足要求。
      4. 特点:
        1. 简单高效
        2. 贪心算法,每一步都选择频数最大的相邻字符进行合并,这种做法可能不一定是全局最优、频数也不一定是最好的合并指标。
        3. 适合拉丁字母组成的语言,不适合汉字、日韩文字等。
    2. WordPiece tokenization,计算过程如下:
      1. 首先将文本拆分成字母和分隔符。
      2. 不同于 BPE 选择合并后词频最大的词作为 SubwordWordPiece 基于语言模型似然概率的最大值生成新的 Subword,具体的基于语言模型似然概率的定义如下:
        1. S=(t1,t2,...,tn)S=(t_1,t_2,...,t_n),句子 Sn 个子词组成。
        2. 则句子 S 的似然概率定义为:logP(S)=i=1nlogP(ti)log P(S)=\sum_{i=1}^n logP(t_i)
        3. 其中 P() 表示一个训练好的语言概率模型。
      3. 找到合并后可以使得句子的似然概率最大的子词合并,更新词表,重复这个过程。
    3. Unigram LM,计算过程如下:
      1. UnigramBPE 以及 WordPiece 有个很大的不同是:
        1. BPEWordPiece 都是初始化小词表逐步变大直到满足词表大小要求。
        2. Unigram LM 是初始化大词表逐步删词直到满足词表大小要求。
      2. Unigram LM 删词的根据和 WordPiece 一致,都是基于语言模型似然概率

3. 预训练数据对大语言模型的影响

与小规模的 PLM 不同,由于对计算资源的巨大需求,通常不可能对 LLM 进行多次预训练迭代。因此,在训练 LLM 之前构建一个准备充分的预训练语料库尤为重要。
目前,不同的 LLM 模型预训练采用不同的预训练策略,下图是一些模型的预训练数据分布图:
LLM_survey_7.png
不过,存在几个有效的混合策略:

  1. 增加数据的多样性(diversity
    预训练阶段,数据的多样性比数据的质量更重要,有实验表明,删除语料库中的多样性数据(例如:Webpages)比删除语料库中的高质量数据(例如:学术语料库)对模型的影响更大。
  2. 可以通过数据混合实验优化数据混合策略
    1. 在大模型上做数据混合实验是非常昂贵且耗时的,通过会在小模型上测试不同的数据混合策略的优劣,再将小模型测试得到的结果用在大模型上。
    2. 但小模型得到的数据混合策略结论在大模型上可能是不成立的,越大的小模型得出来结论越可信。
  3. 先用 general 数据训练模型通用能力,再用 skill-spcific 数据训练模型专业能力
    1. 不同的数据训练的模型有不同的能力,比如:
      1. 用代码训练的模型对数学和编程更擅长。
      2. 用书籍训练的模型更擅长从文本中捕捉长期依赖。
    2. 先训练 basic skill 再训练 target skill 比直接训练 target skill 模型表现更好

4.2 架构设计

LLM_survey_8.png

1. 典型结构

  1. Casual Decoder 结构
    1. 参考 GPT 博客中的 Hello, world! 续写例子
  2. Encoder-Decoder 结构
    1. 参考 T5 博客中的 Hello, world! 英语翻译法语的例子
  3. Prefix Decoder 结构
    1. 是对 Encoder-DecoderCasual Decoder 的折中,在 Encoder 中使用双向注意力,在 Decoder 中使用单向注意力
    2. 用到 Prefix Decoder 的模型有:
      • U-PaLM
      • GLM
  4. Mixture-of-Experts (混合专家)结构
    1. 优势:是一种灵活的模型参数扩展方法;性能提高明显;
    2. 劣势:由于路由操作复杂等原因,训练容易不稳定;
    3. 传言 GPT-4 使用了 MOE 结构
  5. Emergent Architectures(新兴结构)
    LLM_survey_9.png
    1. 现有架构存在的问题:
      1. Transformer 架构一个很大的问题是推理时复杂度较高,每一个 token 需要计算和之前的每一个 token 计算相关性
      2. 相比之下,RNN 架构推理的复杂度就很低,每一个 token 只需要和上一个 token 以及一个不断更新的 hidden state 计算相关性(本质是 hidden state 在某种程度上存储了之前所有 token 的信息)
      3. RNN 数据依赖问题非常强,导致训练难以并行化,且通常效果较差
    2. 一些新兴架构包括:
      1. H3/S4
      2. RWKV
      3. Hyena
      4. Mamba
      5. RetNet
    3. 这些新兴架构几乎无一例外的想做同一件事:Transformer 一样可以并行训练 + 像 RNN 一样高效推理,且效果可以和 Transformer 媲美

2. 配置细节

LLM_survey_11.png

  1. 归一化方法
    1. LayerNorm
      • LayerNormBatchNorm 只有两个差别,为了简化,假设 Channel = 1feature shape = N, 1, H, W
        • 训练时差别:
          • BatchNorm 统计整个 feature map 的均值和标准差(scalar),然后在整个 feature map 做标准正态化;同时记录(滑动平均算法)到 running_mean / running_var 参数中
          • LayerNorm 统计每一个样本的均值和标准差(长度为 Nvector),然后每个样本逐个做标准正态化;均值标准差用完即扔,无需记录
        • 推理时差别:
          • BatchNorm 推理时不需要计算 feature 的均值和标准差,而是使用训练统计得到的 running_mean / running_var,因此是个静态行为,可以被前面的 Conv2d 运算吸收
          • LayerNorm 推理阶段和训练阶段运算方式基本一致
    2. RMSNorm
      • 假设输入 shapeN, C, L 分别表示 batch / feature_dim / seq_length
      • RMS(xc)=1Cn=1Nl=1Lxnl2RMS(x_c)=\sqrt{\frac{1}{C}\sum_{n=1}^N\sum_{l=1}^Lx_{nl}^2}
        RMSNorm(xc)=xcRMS(xc)k+bRMSNorm(x_c)=\frac{x_c}{RMS(x_c)}*k+b
      • 其中,k / b 都是可学习的 per channel 向量
      • LayerNorm 相比 RMSNorm 有如下优势:
        1. 更小的计算开销:RMSNorm 不需要计算输入数据的均值,因此减少了计算量,使得模型训练更加高效。
        2. 训练速度更快:由于减少了计算量,RMSNorm 在训练过程中的速度通常比 LayerNorm 更快。
        3. 性能相当或更好:尽管 RMSNorm 的计算更简单,但它在保持与 LayerNorm 相当性能的同时,甚至可能在某些情况下提供更好的性能。
        4. 保留重要的不变性:RMSNorm 保留了输入数据的均方根比例不变性,这有助于模型在面对不同尺度的输入数据时保持一致的性能。
        5. 隐式学习率适应:RMSNorm 通过归一化输入数据的 RMS,为模型提供了一种隐式的学习率适应能力,有助于模型在训练过程中更好地调整参数。
    3. DeepNorm
      • DeepNorm 可以看做是一种增强型 LayerNorm,对 LayerNorm 改动较小,但效果惊人,DeepNorm 用在 Post-LN 架构上替代传统 LayerNorm 运算,可稳定训练,可训练深度超过 1,000 层的 Transformer
      • DeepNormLayerNorm 的改动如下:
        LayerNorm(x+f(x))LayerNorm(xα+f(x))LayerNorm (x + f(x)) \rightarrow LayerNorm(x*\alpha + f(x))
        LLM_survey_10.png
  2. 归一化位置
    1. Pre-LN
      • Pre-LN 是一种 Transformer 架构,计算公式是:
        x=x+MHA(LayerNorm(x))x=x+MHA(LayerNorm(x))
        x=x+FFN(LayerNorm(x))x=x+FFN(LayerNorm(x))
        x=LayerNorm(x)x = LayerNorm(x)
    2. Post-LN
      • Post-LN 是另外一种 Transformer 架构,计算公式是:
        x=LayerNorm(x+MHA(x))x=LayerNorm(x+MHA(x))
        x=LayerNorm(x+FFN(x))x=LayerNorm(x+FFN(x))
    3. Sandwich-LN
      • Sandwich-LNPre-LN 的改进,公式为:
        x=x+LayerNorm(MHA(LayerNorm(x)))x=x+LayerNorm(MHA(LayerNorm(x)))
        x=x+LayerNorm(FFN(LayerNorm(x)))x=x+LayerNorm(FFN(LayerNorm(x)))
        x=LayerNorm(x)x = LayerNorm(x)
  3. 激活函数
    1. GeLU
      GeLU(x)=0.5x(1+erf(x2))GeLU(x)=0.5x*(1+erf(\frac{x}{\sqrt 2}))
      erf(x)=2π0xet2dterf(x)=\frac{2}{\sqrt \pi}\int_0^xe^{-t^2}dt
      • 其中 erf 表示高斯误差函数,值域是 [-1, 1]
      • GeLULLM 中使用最广泛的激活函数
    2. Swish
      Swish(x)=xsigmoid(x)Swish(x) = x*sigmoid(x)
    3. SwiGLU
      SwiGLU(x1,x2)=Swish(x1)x2SwiGLU(x_1, x_2) = Swish(x_1) * x_2
    4. GeGLU
      GeGLU(x1,x2)=GeLU(x1)x2GeGLU(x_1, x_2)=GeLU(x_1) * x_2
  4. 位置编码
    1. 绝对位置编码
      1. 用在传统 Transformer 上,有两种:
        1. 位置编码(position encoding):使用正弦得到位置编码
          PE(j,2i)=sin(pj100002idmodel)PE(j, 2i)=sin(\frac{p_j}{10000^{\frac{2i}{d_{model}}}})
          PE(j,2i+1)=cos(pj100002idmodel)PE(j, 2i+1)=cos(\frac{p_j}{10000^{\frac{2i}{d_{model}}}})
          • 其中
            • PE(j,2i)/PE(j,2i+1)PE(j,2i)/PE(j,2i+1) 分别表示位置 pjp_j 对应的位置编码向量的第 2i/2i+12i/2i+1 位置的值
            • pjp_j 表示第 jj 个位置
            • dmodeld_{model} 表示向量维度
        2. 可学习位置编码(position embedding):使用可学习的 embedding 编码
          1
          position_embedding = nn.Embedding(max_seq_length, d_model)
      2. 绝对位置编码 position embedding 通常会 element-wise 加到输出 token embedding 作为 Transformer 输入,即:
        xi=xi+pix_i=x_i + p_i
        xix_i 表示 token embeddingpip_i 表示 position embedding
    2. 相对位置编码
      1. 从计算方法来说,相对位置编码和绝对位置编码其实差别不大
        1. 相同点:通常也是使用位置编码(position encoding)和可学习位置编码(position embedding)两种方法
        2. 不同点:以一个 seq_len = 3 的序列为例
          1. 绝对位置编码:结果是一个 3 x dim_model 的位置编码向量
          2. 相对位置编码:
            1. 需要先构造相对位置矩阵:
              [012101210]\begin{bmatrix}0&-1&-2\\1&0&-1\\2&1&0\end{bmatrix}
            2. 将相对位置矩阵使用上述两种方法中的一种进行向量化,输出一个 3 x 3 x dim_model 的相对位置编码
      2. 从使用方法来说,相对位置编码不再需要显式的将 position embedding 加上 token embedding 作为 Transformer 输入,而是将相对位置编码加到 self-attention 上:
        Aij=WqxixjTWkT+rijA_{ij}=W_qx_ix_j^TW_k^T+r_{i-j}
        其中,AijA_{ij} 表示 keyqueryself-attention,也就是说会直接把 relative position embedding 加到 self-attention 上,因此也被称为 RelativePositionBias (相当于 self-attentionbias
    3. 旋转位置编码 RoPE
      1. 是一种不可学习的 position encoding 位置编码方式,编码本身是绝对位置编码,但通过 self-attention 之后,keyquery 会产生相对位置关系
      2. 计算过程:
        1. 首先以固定间隔角度计算旋转矩阵,矩阵中每个元素是复数形式,shape = [max_seq_len, d_model]
        2. 对计算 self-attention 之前的 key / query 分别进行 旋转(本质是和旋转矩阵做复数乘法,然后再转换到实数空间),此步骤不改变 key / queryshape
        3. 然后做标准的 self-attention
    4. 总结
      1. 绝对位置编码position embeddingtoken embeddingshape 相同,作用在 query / key / value 生成之前
      2. 旋转位置编码position embeddingtoken embeddingshape 相同,作用在 self-attention 之前,只作用在 key / query 上,不对 value 生效
      3. 相对位置编码position embeddingtoken embeddingshape 不同,和 attention mapshape 相同,作用在 self-attention 生成的注意力矩阵上
  5. Attention 方式
    1. full attention
      1. 就是标准的 self-attention,即
        Attention(Q,K,V)=softmax(QKTdk)VAttention(Q,K,V)=softmax(\frac{QK^T}{\sqrt {d_k}})V
        Q/K/VRn×dQ/K/V\in\mathbb{R}^{n\times d}
      2. LLM 语境下通常 n >> dsoftmax 是非线性运算,所以需要先计算 QKTRnnQK^T\in\mathbb{R}^{n*n},这决定了 full attention 的计算复杂度为 O(n2)\mathcal{O}(n^2),因此 full attention 复杂度也被称为 softmax 计算复杂度
      3. 假如没有 softmax,那么 QKTVQK^TV 可以通过结合律先计算 KTVRd×dK^TV\in\mathbb{R}^{d\times d},然后再计算 QKTVRn×dQK^TV\in\mathbb{R}^{n\times d},计算复杂度退化为 O(n)\mathcal{O}(n),变成了线性复杂度
    2. sparse attention
      1. 在标准 self-attention 的基础上,提前生成一个固定的二值的 sparse attention mask,将 self-attention (O)(n2)\mathcal(O)(n^2) 的计算复杂度变成 (O)(nn)\mathcal(O)(n\sqrt n)
      2. 固定的二值的 sparse attention mask 可以有多种形式,比如:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      1, 0, 0, 0, 0, 0, 0, 0, 0, 0    |   1, 0, 0, 0, 0, 0, 0, 0, 0, 0
      0, 1, 0, 0, 0, 0, 0, 0, 0, 0 | 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
      0, 0, 1, 0, 0, 0, 0, 0, 0, 0 | 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
      1, 0, 0, 1, 0, 0, 0, 0, 0, 0 | 0, 1, 1, 1, 0, 0, 0, 0, 0, 0
      0, 1, 0, 0, 1, 0, 0, 0, 0, 0 | 0, 0, 1, 1, 1, 0, 0, 0, 0, 0
      0, 0, 1, 0, 0, 1, 0, 0, 0, 0 | 0, 0, 0, 1, 1, 1, 0, 0, 0, 0
      1, 0, 0, 1, 0, 0, 1, 0, 0, 0 | 0, 0, 0, 0, 1, 1, 1, 0, 0, 0
      0, 1, 0, 0, 1, 0, 0, 1, 0, 0 | 0, 0, 0, 0, 0, 1, 1, 1, 0, 0
      0, 0, 1, 0, 0, 1, 0, 0, 1, 0 | 0, 0, 0, 0, 0, 0, 1, 1, 1, 0
      1, 0, 0, 1, 0, 0, 1, 0, 0, 1 | 0, 0, 0, 0, 0, 0, 0, 1, 1, 1
    3. Multi-query/grouped-query attention
      1. 简单来说,MQA 是将标准 MHA 中的 key / valueMulti-Head Attention 退化成 Single-Headquery 保持不变
      2. GQA 是将 Multi-Head 分组,每个组内是 MQA
      3. 具体可以参考 这里这里 两篇博客
    4. Flash attention
      1. 简单来说 Flash attentionFlash attention v2 是标准 self-attention 的完全等价的高效实现,通过更合理的实现大幅降低了 SRAMHBW 之间的 IO 量,从而大幅加速训练 / 推理速度
      2. 详细分析可参考 这里这里 两篇博客
    5. Paged attention
      1. Paged attention 的目的是解决生成式模型 kv cache 占用太多显存导致显存利用率低的问题,kv cache 详细分析可参考 这篇博客
      2. Paged attention 通过类似分页内存管理的方法管理 kv cache 显存,随着序列变长,动态分配显存,显存物理空间不连续,最多只浪费一页,极大提高了显存利用率,使得可以运行更大的 batch size

3. 预训练任务

  1. Language modeling(语言建模)
    1. 语言建模任务是给定一个序列 X={x1,x2,...,xn}X = \{x_1, x_2, ..., x_n\},使得 LLM=i=1nlogP(xiX<i)L_{LM}=\sum_{i=1}^n log P(x_i|X<i) 此极大似然估计最大,其中 X<i={x1,...,xi}X<i=\{x_1,...,x_i\}
    2. 语言建模预训练任务是 LLM 最常用的预训练任务,在很多下游任务上甚至无需 fine-tuning
  2. Denoising Autoencoding(去噪自编码)
    1. 去噪自编码是在一个句子中随机替换 token 为噪声,然后训练模型去恢复原始信息
  3. Mixture-of-Denoisers(混合降噪器)
    1. MoD 是出自 Google UL2 大模型,此大模型使用了 MoD 作为预训练任务,是前面提到的两种预训练任务的组合
      UL2.png

4. 长文本建模

长文本建模是指模型在推理阶段实际输入的序列长度比训练阶段更长,即 train short, test long,主要有两种范式:

  1. 扩展位置嵌入(Scaling Position Embeddings)
    1. 直接模型微调:通过多阶段逐步增加上下文长度来适应长文本。
    2. 位置插值:通过调整位置索引来扩展上下文窗口,相比直接模型微调更有效。
    3. 位置截断:截断超出预定义窗口长度的位置索引,保留局部位置关系。
    4. 基础修改:通过调整基础值来改变波长,以适应更长的文本。例如修改 RoPE 的旋转角度间隔等。
    5. 基础截断:截断超出特定范围的基础值,避免在更大位置索引处出现分布外的旋转角度。
  2. 适应上下文窗口(Adapting Context Window)
    1. 并行上下文窗口:将输入文本分割成多个段,独立编码并修改注意力掩码以访问先前段的令牌。
    2. Λ 形上下文窗口:基于LLMs倾向于更多关注起始和最近的令牌,采用选择性保留初始和最近令牌的注意力掩码。
    3. 外部记忆:存储过去的键(keys)在外部记忆,并使用k-最近邻搜索方法检索最相关的令牌。

5. 解码策略

  1. 背景
    1. 对于绝大多数的文本生成任务,language modeling 解码策略就足够了,即预测下一个概率最大的词,这种解码策略也被称为 Greedy search
    2. language modeling 解码策略对于比如机器翻译、文本总结等任务是够用的,但是对于比如故事生成、对话等任务就有问题,会输出大量重复的、无意义的文本
    3. 因此,一种简单有效的策略是根据输出的词表中每一个词的概率随机选择一个词(即从 argmax 变成 softmax),这种策略被称为 Random sampling
  2. Greedy search 的改进
    1. Beam search:集束搜索可以缓解模型预测陷入局部最优解,beam size 通常设置在 3 ~ 6 之间,太大会降低模型效果
    2. Length penalty:对于集束搜索的搜索空间进行长度惩罚,最终加权选择最优生成序列
  3. Random sampling 的改进
    Random sampling 是根据预测概率随机选,因此没个词都有可能被选中(即使概率很低),这可能会导致输出完全不合逻辑的文本序列,因此需要改进
    1. Temperature sampling
      1. P(xjx<i)=exp(lj/t)jexp(lj/t)P(x_j|x<i)=\frac{exp(l_j/t)}{\sum_{j'}exp(l_{j'}/t)},其中 t 代表温度
      2. 是对 softmax 得到概率分布的优化,加入了温度系数,可有效缓解随机采样导致的采样到不合理值的问题
      3. t = 1 时,退化为 random sampling
      4. t 趋近于 0 时,退化为 greedy search
    2. top-k sampling
      1. 只保留可能性最高的 k 种取值
      2. 概率重新归一化后根据概率随机选
    3. top-p sampling(nucleus sampling)
      1. 只保留累计概率不超过 p 的最小集;也就是按照预测概率降序,保留累计概率小于 p 的样本
      2. 概率重新归一化后根据概率随机选
    4. contrastive search
      1. 参考 这篇博客
      2. 道理上讲得通,但模型推理阶段计算量翻了一倍
    5. typical sampling
      1. 参考 这篇博客
      2. top-p 算法的升级版本
    6. ηsampling\eta-sampling
      1. 参考 这篇博客
      2. 算是一种动态自适应 top-p 算法,参考了 typical sampling

6. 解码效率

作为主流的 GPT-like LLM,解码(推理)可以分为两个阶段:

  1. prefill stage
    1. 预装填阶段,即将 input / prompt 输入到模型中计算 hidden state 的阶段
    2. 此阶段的计算访存比比较高,以 A100 80GB GPU + LLaMA-13B 为例,计算访存比为 113.78(硬件理论最高效计算访存比为 156
  2. incremental decoding stage
    1. 增量解码阶段,即累加上一轮输出持续解码直到 <EOS>max_length
    2. 此阶段计算访存比比较低,以 A100 80GB GPU + LLaMA-13B 为例,计算访存比为 1.97
      因此,通过优化解码效率主要是针对 incremental decoding stage,对于增量解码阶段的优化主要有两个方向:
  3. 减少数据 IO
    1. 这里的数据 IO 是指 HBMSRAM 之间
    2. Flash Attention 通过分块计算 Attention,可大幅降低数据 IO
    3. Multi-Query AttentionGrouped-Query Attention 通过共享/分组共享 KV 来减小 IO
  4. 解码策略优化
    1. 投机解码:用小模型预测序列,让大模型评判是接受还是拒绝,可参考 这篇博客
    2. 树式投机解码 SpecInfer:在投机解码基础上升级,用树结构来存储候选 token,可参考 这篇博客
    3. 跳跃解码 SkipDecode:在模型中跳过一些层的计算以减小计算量,和投机解码的无损加速(和原解码方式输出完全一致)不同,SkipDecode 是有损加速

7. 实际设置

  1. T5
    1. 默认使用贪心解码算法
    2. 对于翻译和总结任务,使用 beam size = 4beam search,长度惩罚系数 0.6
  2. GPT-3
    1. 对于所有任务,使用 beam size = 4beam search,长度惩罚系数 0.6
  3. Alpaca
    1. 对于开放式生成任务,使用随机解码,top-k (k = 50)top-p (p = 0.9) 以及 0.7 的温度
  4. LLaMA
    1. 对于问答任务,使用贪心解码算法
    2. 对于代码生成任务,使用随机解码,温度设置为 0.10.8(分别为 Pass@1Pass@100
  5. Open-AI API
    1. 支持多种解码方式:
      1. greedy search:通过设置温度为 0
      2. beam search:设置 best_of
      3. temperature sampling:设置 temperature
      4. nucleus sampling:设置 top-p
    2. 支持多种控制重复度的方法:
      1. 设置 presence_penalty
      2. 设置 frequency_penalty

8. 架构选择

  1. 目前 causal decoder 是主流的大模型架构,主要原因有两点:
    1. 有证据表明,对于没有 fine-tuning 的情况下,causal decoder 表现比 encoder decoder 架构更好,即对于 zero-shot / few-shot 任务,causal decoder 效果更好
    2. scaling lawcausal decoder 中表现明显,对于 encoder decoder 的研究缺乏

4.3 模型训练

1. 训练配置

  1. Batch Training
    1. 对于 Language model pre-training 任务(例如 bert 等),通常用较大的 batch size,例如 2048 examples 或者 4M tokens,这样通常可以提高训练稳定性和吞吐量。
    2. 对于 LLM 任务(例如 GPT-3 / PaLM),引入了动态 batch size 的做法,GPT-3 在训练过程中会将 batch size32K tokens 逐步增加到 3.2M tokens,动态 batch size 可提高 LLM 训练稳定性
  2. Learning Rate
    1. LLM 的训练通常采用 warmup + decay 的训练策略
    2. warmup 过程通常占总训练 step 数量的 0.1% - 0.5%,学习率逐步从 0 提高到最大值,最大值通常在 5e-5 ~ 1e-4 之间(GPT-36e-5)。
    3. decay 过程通常使用 cosine decay 策略,在剩余的 training step 中逐步将 learning rate 降低到最大值的 10%
  3. Optimizer
    1. 通常使用 Adam / AdamW / Adafactor 优化器中的一种
    2. 对于 Adam / AdamW,超参数配置为 β1=0.9, β2=0.95, ϵ=108\beta_1=0.9,\ \beta_2=0.95,\ \epsilon =10^{-8}GPT-3 就使用了这组配置。
    3. Adafactor 优化器相比 Adam / AdamW,优点是训练过程更省显存,超参数配置为 β1=0.9, β2=1.0k0.8\beta_1=0.9,\ \beta_2=1.0-k^{-0.8}k 表示训练步数,PaLM / T5 就使用了 Adafactor 优化器。
  4. 训练稳定化
    1. LLM 训练不稳定是常见情况,可以会导致训练崩溃
    2. 通常做法有:
      1. weight decay 0.1
      2. gradient clipping to 1.0
    3. 损失函数尖峰(loss spike)也会导致训练不稳定,通常做法有:
      1. 模型回退到 loss spike 出现之前最近一次 checkpoint,且弃用导致 loss spike 的数据,PaLM / OPT 使用了这种方法
      2. GLM 模型发现 Embedding layer 不正常梯度容易导致 loss spike,因此缩小了 embedding layer gradient

2. 可拓展性训练技术

  • LLM 训练会有两个技术难题:训练吞吐量的增加加载大模型到显存,解决方法包含以下几种(以下几种并不冲突,可以同时使用):
    1. 3D Parallelism
      1. Data parallelism
        1. 主流框架都已有实现(例如 pytorchddp
        2. 划分数据到不同 GPU,每个 GPU 独立前向反向
        3. 每个 stepgradient 都需要聚合一次,以确保每个 GPU 上参数更新保持一致
      2. Pipeline parallelism
        1. 模型不同的层放到不同的 GPU 上训练,由于 LLM 基本都是 Transformer 架构,所以一个 GPU 通常会加载连续的几层,这样可以有效降低 hiddent stategradient 通信量
        2. GPU one-by-one 计算会导致 GPU 利用率很低(流水存在大量气泡),需要有效的排计算流水
        3. GpipePipeDream 可以通过重整数据 batch 和异步梯度更新提高 GPU 利用率
      3. Tensor parallelism
        1. Tensor parallelism 是把模型一层的参数切成多份,每份独立计算,因此也叫做 Model parallelism
        2. Pipeline parallelism 是横向把模型切成几段,而 Tensor parallelism 是纵向把模型切成几段。
        3. Y=X@AY=X @ A 矩阵乘运算为例,Tensor parallelism 是将 A 纵向切分为 [A1,A2][A_1,A_2] 放到不同的 GPU 上独立运算,则 Y=[X@A1,X@A2]Y=[X@A_1,X@A_2]
        4. Tensor parallelism 需要分析每个算子的数据依赖情况,比如矩阵乘的右矩阵可以按列划分,但不可以按行划分。
        5. 目前一些开源框架都支持了 Tensor parallelism,例如 Megatron-LM (可参考 这篇博客) 和 Colossal-AI
    2. ZeRO
      1. 通过分片存储等方法降低冗余,ZeRO-DPZeRO-R 可参考 这篇博客
      2. FSDPPyTorch 官方提出和实现的类似于 ZeRO 的算法,全称是 Fully Sharded Data Parallel
        1. 代码:https://github.com/facebookresearch/fairscale
        2. 文章:https://engineering.fb.com/2021/07/15/open-source/fsdp/
    3. 混合精度训练
      Format Bits Exponent Fraction
      FP32 32 8 23
      FP16 16 5 10
      BF16 16 8 7
      1. FP16FP32 混合训练是比较常见的操作,但最近有研究发现 FP16 会造成模型精度降低。
      2. BF16 是为了解决 FP16 造成精度降低而提出的数据类型,全称是 Brain Floating Point,这种数据类型牺牲了表达精度,提高了表达范围。
    4. 总体训练建议
      1. 3D Parallelism
        1. 在实际应用中,3D Parallelism 通常是联合使用的,例如 BLOOM 模型,是用了:
          • 4Tensor Parallelism
          • 8Data Parallelism
          • 12Pipeline Parallelism
            384 (384=4 x 8 x 12)A100 GPU 训练得到的。
        2. DeepSpeedColossal-AIAlpa 等开源库都对三种并行支持较好
      2. 减小显存占用
        1. ZeROFSDP 等算法可有效降低大模型训练过程中的显存占用,从而可以训练参数量非常大的模型。
        2. DeepSpeedPyTrochMegatron-LM 等开源库都已集成此功能。
      3. predictable scaling
        1. GPT-4 提出的,在小模型上等效预测放大后模型的效果,对超大规模网络训练来说必不可少。

5. LLM 的适配微调

  • 大模型在预训练结束之后,需要适配微调来使得大模型释放全部能力以及对齐人类的三观,主要的微调方式有两种:
    • Instruction Tuning(指令微调):用来提高或解锁大模型在某些方面的能力。
    • Alignment Tuning(对齐微调):对齐人类三观。

5.1 Instruction Tuning 指令微调

  1. Instruction Tuning 可以大幅提高 LLM 的指令遵循能力,即让 LLM 可以解决具体的任务(指令)
  2. Instruction Tuning 通常需要两步:
    1. 收集指令数据:通常是构造结构化数据
    2. 使用收集到的指令数据用监督学习的方法微调 LLM

1. 格式化实例的构造

LLM_survey_12.png

  • 本文用三种(主要的)数据上格式化实例的构造举例:
    1. 格式化 NLP 任务数据(如图 11.a
    2. 格式化日常对话数据(如图 11.b
    3. 格式化人工合成数据(如图 11.c
  1. 格式化 NLP 任务数据
    1. 这里的 NLP 任务是指常见的自然语言任务,例如:
      1. 文本总结(text summarization
      2. 文本分类(text classification
      3. 翻译(translation
    2. 格式化的 NLP 任务数据通常由四部分组成:
      1. 任务描述(Task description
      2. 示例(Demonstrations
      3. 输入
      4. 输出
    3. 任务描述部分很重要,去掉之后微调效果下降明显
    4. PromptSource 是个很好用的格式化 NLP 任务数据的开源工具,提供了很多任务模板,同时提供了一个开源 Prompt 集合数据集称为 Public Pool of Prompts (P3)
  2. 格式化日常对话数据集
    1. NLP 数据集上的格式化实例缺乏 Prompt 的多样性,且和人类实际需求不匹配
    2. 日常对话数据集主要包含两部分:
      1. 任务描述(Task description
      2. 输出
    3. 这两部分都由人类完成,其中:
      1. 任务描述来自于 ChatGPT API 收集到的问题以及人类标注员,内容包含:
        1. 开放内容生成(opened generation
        2. 开放问答(open question answering
        3. 头脑风暴(brainstorm
        4. 聊天(chatting
      2. 输出全部由人类标注员完成
  3. 格式化人工合成数据
    1. 以上两种数据集的格式化实例的方法要么需要大量的标注员,要么需要大量的手动收集,格式化人工合成数据是个半自动方法。
    2. 原理是通过将已收集的格式化数据输入到大模型中,让大模型给出相似的实例。
    3. 步骤:
      1. 首先用少量人工标注的格式化数据作为样本放入样本库
      2. 大模型从样本库中随机采样,仿照样本格式输出另外一个相似的实例
      3. 过滤生成实例的质量,如果没问题则加入样本库中,重复第一步
  4. 格式化数据过程中的关键因素
    1. 指令的缩放法则(Scaling the instructions
      1. 指令微调数据集中涉及到的任务种类越多,多样性越丰富,效果就越好
      2. 一种任务中的实例数量不需要很多,大模型容易饱和
    2. 格式设计(Formatting design
      1. 必须包含任务描述,任务描述对 LLM 理解任务至关重要
      2. 适当数量的演示示例可以降低模型对指令工程的敏感性
      3. 引入 CoT (Chain-of-Thought) 和非 CoT 数据会让 LLM 在需要多跳推理能力的任务和不需要多跳推理的任务上表现好
      4. 引入其他信息(例如: 避免的事项、原因和建议等)对 LLM 性能影响较小或会产生负面影响
    3. 总结
      1. 指令数据集的多样性和质量比数量更重要
      2. 标注员编写人类需求实例比特定于数据集的任务更有用,但人力成本较高
      3. 为减少人力成本,LLM 自动构建指令数据集是一种有效的方法

2. 指令微调策略

  1. 平衡数据分布
    1. 最简单的也是应用最广泛的方法是:混合所有数据,然后平等的采样每一个样本
    2. 有研究表明,对于高质量的数据集,应该适当提高其采样概率
    3. 需要设置采样上限,防止较大数据集主导整个指令微调过程
    4. 每个数据集所侧重的能力不同,用单一数据集微调无法全面增强模型容量,通常需要多种类型的数据混合微调,例如:
      1. NLP 任务数据集(FLAN v2
      2. 聊天数据集(ShareGPT
      3. 合成数据(GPT4-Alpaca
  2. 预训练与指令微调联合训练
    1. 有些模型预训练阶段是个多任务模型,一个任务是常规预训练,另一个任务是指令对齐任务,例如 OPT-IML 模型
    2. 有些模型预训练阶段的数据中混入了一小部分格式化后的指令对齐数据,在预训练过程中就完成了指令对齐,例如 GLM-130BGalactica
  3. 多阶段指令微调
    1. 指令微调数据集大体上分为两种:任务格式化指令对齐数据和日常对话指令微调数据
    2. 其中任务格式化指令数据通常数据量更大,数据集的平衡是非常重要的,因此通常需要非常小心的平衡两种数据
    3. 另外一种更简单的方法是将两种数据分成两个阶段分别训练,例如:先用任务格式化指令数据微调,然后再用日常对话指令数据微调
    4. 实际应用中为了防止能力遗忘问题(Capacity forgetting issue),通常在日常对话指令数据微调过程中加入少量任务格式化指令数据
  4. 一些其他微调技巧
    1. 多轮对话数据的高效微调方法
      1. 对于人机多轮对话数据,通常的做法是将其拆分成多组问答对,然后每对对话数据单独训练,这种训练方式会有对话内容重叠的问题
      2. 一种高效的多轮对话数据微调方法是将整个对话一次送入 LLM 微调,且只对 机器输出的对话部分计算损失
    2. 建立 LLM 的自我认知
      1. LLM 建立自我认知对于部署应用 LLM 很有必要,例如:名称、开发者和隶属关系
      2. 一种实用的方法是 构建自我认知相关的微调指令,也可以加入带有自我认知相关的提示前缀,例如:”以下是人类和 AI 助手之间的对话“

3. 指令微调的作用

  1. 提升模型表现
    1. 指令微调已经成为提升模型能力和解锁模型部分能力的重要方法
    2. 大模型和小模型都可以在指令微调过程中获得收益,模型越大收益越大
    3. 经过指令微调过的小模型比没有经过指令微调的大模型效果更好
    4. 指令微调不止可以用于 LLM,预训练 NLP 模型也可以用
    5. 此外指令微调的计算代价和数据量和预训练过程相比很小
  2. 任务泛化
    1. 大量研究表明,指令微调可以使大模型在见过和没有见过的任务上都表现良好(也可以认为指令微调可以使大模型获得任务泛化的能力)
    2. 指令微调甚至可以缓解大模型的部分缺点,例如重复生成
    3. 指令微调可以让大模型泛化到跨语言种类的相似任务上,例如 BLOOMZ-P3 是在 BLOOM 上仅用纯英文数据 P3 微调得到的,经测试发现在多语种语句补全任务上,BLOOMZ-P3BLOOM 提升超过 50%,表明即使用纯英文数据做指令微调,可以提高大模型在其他语言上的表现
    4. 研究表明,仅用纯英文数据做指令微调,即可解决多语种任务的性能
  3. 任务专业化
    1. 在专业领域指令数据上上做指令微调,大模型可以变成专业模型,例如:在医疗、法律、金融等指令微调数据集上做微调

4. 指令微调经验性的分析

  1. 指令微调数据集
    1. 任务相关的指令数据
      • 常用的数据集是 FLAN-T5 包含 1836 个任务的超过 15M 条指令数据
    2. 日常对话指令数据
      • 常用的数据集是 ShareGPT,包含 63K 条真实用户指令
    3. 合成指令数据
      • 常用的数据集是 Self-Instruct-52K 包含 52K 条指令对共计 82K 个实例的输入输出
  2. 微调效果提升策略
    1. 提升指令的复杂性
      • 可以参考 WizardLM 设计,通过增加约束、提高推理步骤、提高输入复杂度的方式,逐步提高指令的复杂性
    2. 提升指令数据集话题的多样性
      • 合成数据通常会有话题多样性差的问题,可以通过更强的 LLM 对其进行话题多样性扩写,例如用 ChatGPT 扩写 Self-Instruct-52K 数据
    3. 提升指令数据量
      • 在指令质量不下降的情况下,尽可能提高指令数据量
    4. 平衡指令的困难程度
      1. 指令太简单或太复杂都会影响模型微调,容易出现训练不稳定或过拟合的问题
      2. 需要去除数据集中太简单或太复杂的指令
      3. 可以通过用 LLaMa 推理指令输出的困惑度来对指令的困难程度排序,删除过难过易的样本
  3. 实验设置和结果分析
    1. 本节是 Survey 的作者亲自做的指令微调实验的设置和结果分析
    2. 实验设置
      1. 模型:对 LLaMa 做指令微调,包括 LLaMa-7BLLaMa-13B 两个模型
      2. code base: [YuLan-Chat](https://github.com/RUC-GSAI/YuLan-Chat) 一个作者实验室开源的代码
      3. 硬件环境:一台 8A800-80G GPU 服务器
      4. 超参数:和 [Stanford Alpaca](https://github.com/tatsu-lab/stanford_alpaca) 指令微调超参数相同(Stanford Alpaca 是一个基于 LLaMa 的指令跟随模型)
      5. 微调配置:分成 Chat settingQA setting 两个微调配置
        1. Chat setting:
          1. 利用来自日常对话的用户指令和请求做微调
          2. 微调实验:
            1. baseline(对照组):在 Self-Instruct-52K 上微调的 LLaMa-7BLLaMa-13B 模型
            2. 实验组:用上面提到的更科学的数据集和数据集混合方法得到的指令微调数据
          3. benchmark[AlpacaFarm evaluation set](https://github.com/tatsu-lab/alpaca_farm)
          4. 对比方法:对于 benchmark 的每一条数据,用实验组和对照组的两个模型分别推理给出结果,让 ChatGPT 评判哪个更好,最后比较胜率
        2. QA setting:
          1. 利用来自已有的 NLP 任务的问答数据集做微调
          2. benchmark[MMLU (Massive Multitask Language Understanding)](https://arxiv.org/abs/2009.03300)[BBH (BIG-Bench Hard)](https://arxiv.org/abs/2210.09261) 数据集
      6. Prompt
        1. “The following is a conversation between a human and an AI assistant. The AI assistant giveshelpful, detailed, and polite answers to the user’s questions.\n[|Human|]:{input}\n[|AI|]:”.
        2. 在微调训练和 benchmark 推理时都加
    3. 结果分析
      1. NLP 任务格式化指令数据对 QA setting 任务有效,对 Chat setting 任务无效
      2. 混合多种不同的指令数据对提高模型理解能力有帮助
      3. 提高指令的复杂性和多样性主导了指令微调效果的提升
      4. 简单提高指令的数量可能没有收益,平衡指令的困难程度也不总是有效的
      5. 模型越大,指令微调效果越好
    4. 指令微调建议
      1. 提前准备计算资源(GPU
      2. Alpha 开源库做微调
      3. 选择合适的开源预训练 LLM 模型和指令微调数据集,开始微调
      4. 如果计算资源有限,可以考虑 LoRA 等微调方式
      5. 对于部署,可考虑使用低比特量化等方法减小计算量

5.2 Alignment Tuning 对齐微调

1. 背景和对齐标准

  1. 背景
    1. 大模型在很多 NLP 任务中表现出非凡的能力,但有时会生成一些负面的内容,例如:
      1. 伪造虚假信息
      2. 追求不正确的目标
      3. 生成错误、误导或带有偏见的表达
    2. 出现这种问题的原因通常是在预训练数据中混入了负面内容,但预训练数据太大,清洗是不现实的
    3. 因此才出现了对齐微调,对齐微调的目标是 3Hhelpfulness / honesty / harmlessness
    4. 对齐微调可能会损伤大模型原有的生成能力,这也被称为 alignment tax(对齐税)
  2. 对齐标准
    1. Helpfulness 帮助性
      1. 尽可能简洁高效的帮助人类解决任务或回答问题
      2. 当需要更高层次的阐明时,大模型应展现出提出相关的问题来获取额外信息的能力,并且在这个过程中表现出适当的敏感度、洞察力和审慎性
      3. 做帮助行为对齐是一件有挑战的事,因为很难精确定义和衡量用户的意图
    2. Honesty 诚实性
      1. 应该给出诚实的回答而不是伪造的信息
      2. 为避免产生任何形式的欺诈和虚假陈述,大模型应该适当传达出其输出的不确定性
      3. 模型应该了解自身的能力边界
      4. HelpfulnessHarmlessness 相比,Honesty 更客观,因此对齐需要的人力付出会更少
    3. Harmlessness 无害性
      1. 模型输出不应包含冒犯或歧视
      2. 当模型被诱导做出危险行为时,应礼貌的拒绝
      3. 但如何定义有害涉及到使用模型的用户、问题类型以及上下文
    4. 总结
      1. 以上三种对齐标准都比较主观,都是基于人类感知定义的,因此直接量化然后去优化是比较难的
      2. 一种有效的方法是:红队对抗,即让人类对于输入产生违反上述对齐标准的输出,然后让模型将这些作为反面教材去优化

2. 收集人类反馈

人类反馈在对齐微调大模型的过程中至关重要

  1. 人类标注员应如何选择
    1. 基本要求:
      1. 学历好:至少本科学历
      2. 英文好:英语母语
    2. 为了减小研究员和标注员的不匹配,需要研究员和标注者分别标注少量样本,然后选择标注员中和研究员标注相似性高的作为后续标注员
    3. 在标注员中选择一个优秀的超级标注员团队,这个团队更高优先级的为大模型标注对齐数据
  2. 如何收集人类反馈
    1. 基于排序的方法
      1. 最早的标注方式是:仅选择候选列表中标注员认为最优的选项,且由于每个标注员的偏好不同,这会导致人类的反馈不准确或不完整
      2. 基于排序的方法是:系统会自动从候选列表中选择两个选项,标注员选择哪个更好,系统根据标注员的选择对整个候选列表排序,这样可以有效降低不同标注员偏好不同导致的偏差,标注信息更完整
    2. 基于问题的方法
      1. 标注员回答研究员提问的问题,这种类型的标注信息细节丰富,涵盖了对齐标准和其他约束
    3. 基于规则的方法
      1. 通过人为书写的规则自动判断模型输出是否有毒有害

3. RLHF 人类反馈的强化学习

  1. RLHF 系统
    1. 包含三个关键组成部分
      1. 一个用于对齐微调的预训练 LLM
      2. 一个基于人类反馈训练的奖励模型
      3. 一套强化学习算法
    2. 预训练模型作为对齐的起点
      1. InstructGPT 175B 是在预训练的 GPT-3 上对齐的
      2. GopherCite 280B 是在 Gopher 上对齐的
    3. 奖励模型用于评价人类对模型输出的偏好程度
      1. 使用人类偏好数据,可以是一个 LM 的微调,也可以是 LM 从头训练
      2. 通常比 LLM 参数量少,例如 OpenAI6B GPT-3 作为 Reward ModelDeepMind7B Gopher 作为 Reward Model
    4. 强化学习算法用奖励模型的信号去微调预训练大模型
      1. 近端策略优化算法 PPO (Porximal Policy Optimization) 比较常用
  2. RLHF 关键步骤
    LLM_survey_13.png
    1. 有监督微调
      1. 通常以“指令 —— 输出”数据对形式构造,做有监督微调
      2. 通常由人类标注员标注得到,需要包含较丰富的多样性
      3. 在一些特定场景的 RLHF 中,此步骤可以跳过
    2. 训练奖励模型
      1. 通常由 LM 生成对每个指令生成一系列输出,由人类标注员对输出进行 偏好排序 作为训练数据
      2. 奖励模型实际是在模仿人类标注员的偏好
      3. 通常训练得到的奖励模型更偏向于无害但无帮助的回答,这被称为 规避问题(evasion problem)
      4. 最近有一些工作用 AI Agent 代替标注员对 LM 的输出进行偏好排序(RLAIF开始套娃AI Agent 的排序原则是预设的指令对齐原则,这种方式的优势是:
        1. 可以缓解规避问题,生成无害且有帮助的回答
        2. 降低对标注员的依赖,降本增效
    3. 强化学习微调
      1. 用强化学习的方式对第一步微调后的 LM 进行训练,其中强化学习的各个要素分别为:
        1. 策略(policy):微调后的 LM
        2. 动作空间(action space):LM 的词表
        3. 状态(state):目前生成的 token 序列
        4. 奖励(reward):由第二步训练得到的 RM 提供
        5. 为了防止模型退化(逐渐偏离预训练行为),通常在奖励函数中加入一项惩罚项,例如:InstructGPT 通过在奖励函数中加入当前模型输出和微调之前的模型输出之间的 KL 散度,缓解模型的退化问题
        6. 通常重复迭代第二步(RM 的训练)和本步(强化学习微调),可以得到较好的模型
  3. RLHF 实践策略
    成功实现 RLHF 是比较困难的,这里提供一些实践上的策略和技巧
    1. 奖励模型如何有效训练
      1. 大的奖励模型在评判大模型输出质量方面更优
        1. 在实践中,奖励模型有小模型(例如:InstructGPT6B GPT 作为奖励模型)和大模型(和对齐模型一样大或者更大的模型作为奖励模型)两条路线,其中大模型路线在评判 LLM 输出质量方面更优
        2. 可以用 LLM 预训练过程中的检查点参数初始化 RM,这样可以缓解由于预训练数据不一致导致的对齐策略不匹配问题,LLaMa 2 就是这么做的
        3. 大的奖励模型训练容易过拟合,用人类标注的对齐数据的提示词首选响应作为正则化项可以缓解过拟合
      2. 训练一个满足所有对齐标准的奖励模型很难,可以用多个对齐模型的组合来实现,每个对齐模型只关注部分对齐标准
        1. 例如每个奖励模型只关注一项标准,然后用某种策略(例如平均或加权)组合每一种奖励模型的奖励值作为最终奖励
        2. 使用这种方法可以手动条件每一项对齐标注的严格程度(通过调节权重)
    2. 强化学习过程如何有效训练
      1. 强化学习通常是不稳定且超参数敏感的,因此需要在强化学习前模型已经得到充分的有监督训练
      2. 常用的方法是:
        1. 收集多样性较为丰富的对齐数据输入,通过采样策略让 LLM 对每个输入推理得到 N 个输出
        2. 用奖励模型评判 N 个输出,得到最优的输出
        3. 用“输入 —— 最优输出”数据对有监督训练 LLM,知道模型的表现不再提升(收敛)
      3. 需要有部分人类标注的对齐数据 benchmark 用来真实地评价模型对齐效果
      4. 通常需要奖励模型和强化学习优化过程的多轮迭代
    3. 强化学习过程如何高效训练
      1. 强化学习过程和奖励模型训练多轮迭代会带来巨大的存储和计算开销
      2. 可以将奖励模型部署在单独的服务器上,通过 API 调用
      3. 对齐模型对于每个指令需要同时输出多组候选输出,用集束搜索算法(beam search)效率更高,且可以提高输出的质量和多样性
  4. RLHF 的过程监督
    1. RLHF 的监督可以分为两种:
      1. 对结果监督:监督 LLM 对于输入指令的完整输出
      2. 对过程监督:更细粒度的监督 LLM 的输出过程,例如输出的每个句子、每个单词、每个推理步等
    2. 过程监督数据集:PRM800K
      1. PRM800KOpenAI 开源的 RLHF 过程监督数据集,可以用其训练 PRM (Process-supervised Reward Model) 过程监督奖励模型
      2. PRM800K 包含:
        1. 12K 个过程标注的数学问题
        2. 75K 个由 LLM 生成的解法
        3. 800K 个过程正确性标签,标签分为:
          1. Positive 正面
          2. Negative 负面
          3. Neutral 中性
    3. 过程监督可以和专家迭代强化学习算法(Expert Iteration (EXIT))结合

4. 不用 RLHF 的对齐

  1. RLHF 做对齐微调的痛点
    1. 需要训练被对齐模型和奖励模型,同时需要频繁推理参考模型(对齐前的模型,不训练,用于防止对齐过程导致模型退化),存储和计算代价大
    2. RLHF 过程中常用的 PPO 算法非常复杂,且对超参数敏感
  2. 不用 RLHF 的对齐如何做?
    1. SFT 代替 RLHF,即用基于有监督微调代替基于人类反馈的强化学习
    2. 这种方法假设 LLM 可以从对齐数据集中学习到对齐行为
    3. 这种方法包含两个关键:构建对齐数据集设计微调损失函数
  3. 构建对齐数据集
    对齐数据集的构建主要包含三种方法:基于奖励模型的方法基于大模型的生成方法基于大模型的互动方法
    1. 基于奖励模型的方法
      1. 从生成模型中采样一批数据
      2. 使用奖励模型对其进行评分,筛选出高质量样本(或对样本进行质量分组)
      3. 用奖励模型的输出做为监督信息,微调 LLM
      4. 使用这种方法的算法有:
        1. RAFT
        2. Quark
        3. ILF
      5. 一些好用的开源奖励模型:
        1. OpenAssistant 开源的 DeBERTa 系列奖励模型
        2. 复旦大学开源的 Moss-7B 奖励模型
        3. 斯坦福大学开源的 Flan-T5-xl 奖励模型
      6. 基于奖励模型的方法存在的问题:
        1. 奖励模型本身的训练需要大量对齐标注数据,这些数据是难以获得且昂贵的
        2. 尽管已有的奖励模型可以复用,但它们可以无法准确捕捉到另外一个独立训练的大模型的不对齐行为
    2. 基于大模型生成的方法
      1. Constitutional AI 将人类监督映射为一组原则(自然语言指令的集合),让 LLM 重复的用这组原则批判并修正自己的输出
      2. Self-Align 是先用 Self-Instruct 方法生成多样性强的指令数据集,然后模型会被提示多个人类编写的原则,这些原则描述了期望的模型规则和行为,以生成符合 3H 标准的数据用于对齐训练
      3. FIGA 采用正样本(LLM 精炼后的输出)和负样本(原始到低质量输出)对比学习的方法,缓解了 SFT 只能用正样本监督学习的问题,使 LLM 能够深入理解哪些细粒度的修改实际上导致了良好的响应
    3. 基于大模型交互的方法
      1. 传统大模型训练都是孤立的,没有外部反馈信号来改进自己
      2. Stable Alignment 通过多个 LLM 交互来获得改进的反馈,从而实现自我改进
  4. 有监督对齐微调
    有监督对齐微调有点类似于指令微调,主要的训练损失函数依然是 Sequence-to-Sequence 的交叉熵损失,但一些研究提出对主要训练目标的改机,并提出了一些辅助损失,可用于挖掘对齐数据集的潜力,提高对齐质量
    1. 主要训练目标
      1. CoT (Chain of Hindsight) 对有监督微调数据集中的正负样本分别添加“一个有帮助的回答”和“一个没有帮助的回答”两种指令,且仅对有特殊掩码的响应标记计算损失
      2. Quark 将模型响应数据(对齐监督训练数据)按对齐质量分成不同的分位数,每个监督数据前加入一个特殊的奖励 token,用于表示响应的奖励等级
      3. DPO (Direct preference optimization) 将大模型本身用于奖励模型,从而不需要显式的奖励模型
      4. FIGA 定义细粒度对比学习损失
    2. 辅助训练目标
      1. 排序损失
        1. 由于奖励模型可以给每一个响应评分,所以收集同一条指令的多组响应可以排序,可以计算排序辅助损失
        2. RRHF 模型就在 SFT 对齐训练中加入了排序辅助损失
      2. 相似性损失
        1. 模型的响应和人类偏好的相似性可以通过计算潜在空间中的距离来得到
        2. SLiC-HF 就增加了相似性损失函数来对齐响应和人类偏好
      3. 对比学习损失
        1. 对比学习可以用来提高正确的 “指令 —— 响应” 对的概率,降低错误的 “指令 —— 响应” 对的概率,这样做可以使模型学会指令和响应之间的正确相关性。
  5. 总结
    1. RLHF 是用对齐数据训练一个 RM,然后用 RM 指导模型微调(给模型的响应打分)
    2. SFT 是直接用对齐数据微调模型
    3. 二者对比来看,RLHF 学习的是响应级监督,而 SFT 学习的是 token 级监督
    4. SFT 微调的模型,在遇到对齐微调数据集之外的数据时,更倾向产生幻觉,尤其是在对齐微调数据集是由大模型生成的时候
    5. 由于没有奖励模型做标注质量过滤,SFT 对标注质量更敏感
    6. RLHF 对缓解有害输出和增强模型能力方面非常有效,在 LLaMa 2 中,RLHF 同时提高了模型的帮助性和无害性得分,并将其归功于 RLHF 实现了一种更优的 “LLM —— 人类” 交互方式
    7. RLHF 实际上是通过鼓励 LLM 通过对比自己生成内容的 “好” 和 “不好” 评价,找到一种纠正策略;而不是像 SFT 一样,强制让模型去模仿 “好” 的外部内容(非自我生成)
    8. RLHF 可以减轻幻觉行为,这一点在 GPT-4 中被证实
    9. 传统强化学习的缺点,RLHF 一样不少,比如样本效率低下和训练稳定性差
    10. RLHFLLM 必须先用 SFT 预训练收敛的参数初始化
    11. RLHF 需要标注员参与到复杂的迭代过程中,不能像 SFT 一样标注和训练解耦
    12. RLHF 的结果对实验过程细节非常敏感,例如:
      1. 提示词的选择
      2. 奖励模型和 PPO 的训练策略
      3. 超参数设置
    13. SFT 可以提高预训练模型的容量,RLHF 可能会提高 SFT 的模型容量
    14. RLHF 过程还比较原始,需要探索和优化的点还有很多

5.3 参数高效的模型适配微调

  1. 参数高效的微调方法
    大模型参数量太多,微调全部参数对大多数用户不可实现,因此 参数高效的微调方法 主要是通过降低微调过程中可学习的参数量实现参数高效的微调,主要方法有四种,如图:
    LLM_survey_14.png
    1. Adapter Tuning 适配器微调
      1. 适配器微调论文出自 2019Parameter-Efficient Transfer Learning for NLP,是 Bert 时代的产物
      2. 本质是在 标准 Transformer 模型预训练结束后,在每个 Transformer block 中加入两个 Adapter block,其他参数冻结,只微调 Adapter block
      3. Adapter block 中包含降采样(Down project)算子,因此计算量和参数量都较小
      4. Adapter blockTransformer block 中的位置以及 Adapter block 长什么样?
        LLM_survey_15.png

        图中所有的绿色块表示微调过程中可训练的参数

    2. Prefix Tuning 前缀微调
      1. 前缀微调的基本假设是:预训练之后的大模型实际上已经完全具备解决任何下游任务的能力,只需要找到合适的提示词(不一定是词表中的词)即可。
      2. 开山之作是斯坦福的 Prefix Tuning,详细分析可参考 这篇博客
      3. 然后是谷歌的小修改版本,Prompt Tuning,详细分析可参考 这篇博客